//
//  UserDefaultProperty.swift
//  EasyCoding
//
//  Created by JY_NEW on 2020/6/4.
//

import Foundation

///提供UserDefaults访问
@propertyWrapper
public struct PWUserDefault<T> {
    ///这里的属性key 和 defaultValue 还有init方法都是实际业务中的业务代码
    ///我们不需要过多关注
    let key: String
    let defaultValue: T
    let userDefaults: UserDefaults = .standard
    
    public init(_ key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }
    ///  wrappedValue是@propertyWrapper必须要实现的属性
    /// 当操作我们要包裹的属性时  其具体set get方法实际上走的都是wrappedValue 的set get 方法。
    public var wrappedValue: T {
        get {
            return userDefaults.value(forKey: key) as? T ?? defaultValue
        }
        nonmutating set {
            if let optional = newValue as? PWAnyOptional, optional.isNil {
                userDefaults.removeObject(forKey: key)
            } else {
                userDefaults.setValue(newValue, forKey: key)
            }
        }
    }
    /// 提供外部访问
    public var projectedValue: Self {
        return self
    }
    public func remove() {
        userDefaults.removeObject(forKey: key)
    }
}

internal protocol PWAnyOptional {
    var isNil: Bool { get }
}

extension Optional: PWAnyOptional {
    var isNil: Bool { self == nil }
}

public extension PWUserDefault where T: ExpressibleByNilLiteral {
    init(_ key: String) {
        self.init(key, defaultValue: nil)
    }
}

extension PWUserDefault {
    ///提供UserDefaults值的引用，使用时可用PWUserDefault.Refer($PWUserDefault值)
    @propertyWrapper
    public struct Refer {
        let value: PWUserDefault<T>
        public init(_ value: PWUserDefault<T>) {
            self.value = value
        }
        public var wrappedValue: T {
            get {
                return self.value.wrappedValue
            }
            nonmutating set {
                self.value.wrappedValue = newValue
            }
        }
        /// 提供外部访问
        public var projectedValue: PWUserDefault<T> {
            return self.value
        }
    }
}
